﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.Serialization;

using SharpGL.Media3D;

namespace SharpGL.SceneGraph.Primitives.Text
{
    /// <summary>
    /// A text object text in specified point.
    /// </summary>
    [DataContract(IsReference = true)]
    public class Text2DObject : TextObject
    {
        #region Private Fields

        /// <summary>
        /// The horizontal text alignment.
        /// </summary>
        private HorizontalAlignment horizontalAlignment = HorizontalAlignment.Left;

        /// <summary>
        /// The vertical text alignment.
        /// </summary>
        private VerticalAlignment verticalAlignment = VerticalAlignment.Bottom;

        #endregion Private Fields

        #region Protected Methods

        /// <summary>
        /// Perform all rendering operation to the provided instance of OpenGL.
        /// </summary>
        /// <param name="gl">The OpenGL instance.</param>
        /// <param name="renderMode">The render mode.</param>
        protected override void InternalRenderText(OpenGL gl, RenderMode renderMode)
        {
            if (OpenGL.IsValidContext(gl))
            {
                Point3D screenPosition = gl.Project(Position);
                Size textSize = gl.GetTextSize(Font, Text);

                switch (HorizontalAlignment)
                {
                    case HorizontalAlignment.Left:
                        break;
                    case HorizontalAlignment.Center:
                        screenPosition.Push(-textSize.Width / 2.0f, 0.0f, 0.0f);
                        break;
                    case HorizontalAlignment.Right:
                        screenPosition.Push(-textSize.Width, 0.0f, 0.0f);
                        break;
                    default:
                        break;
                }

                switch (VerticalAlignment)
                {
                    case VerticalAlignment.Top:
                        screenPosition.Push(0.0f, -textSize.Height, 0.0f);
                        break;
                    case VerticalAlignment.Center:
                        screenPosition.Push(0.0f, -textSize.Height / 2.0f, 0.0f);
                        break;
                    case VerticalAlignment.Bottom:
                        break;
                    default:
                        break;
                }
                
                gl.DrawText((int)screenPosition.X, (int)screenPosition.Y, Font, Text);
            }
        }

        #endregion Protected Methods

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Text2DObject"/> class.
        /// </summary>
        public Text2DObject()
		{
			Name = "Text 2D object";
		}

        #endregion Constructors

        #region Public Propetries

        /// <summary>
        /// Gets or sets the horizontal text alignment.
        /// </summary>
        /// <value>
        /// The horizontal text aligment.
        /// </value>
        [Description("The horizontal alignment."), Category("Text object")]
        public virtual HorizontalAlignment HorizontalAlignment
        {
            get { return horizontalAlignment; }
            set
            {
                if (horizontalAlignment != value)
                {
                    horizontalAlignment = value;

                    NotifyPropertyChanged("HorizontalAlignment");
                }
            }
        }

        /// <summary>
        /// Gets or sets the vertical text alignment.
        /// </summary>
        /// <value>
        /// The vertical text aligment.
        /// </value>
        [Description("The vertical alignment."), Category("Text object")]
        public virtual VerticalAlignment VerticalAlignment
        {
            get { return verticalAlignment; }
            set
            {
                if (verticalAlignment != value)
                {
                    verticalAlignment = value;

                    NotifyPropertyChanged("VerticalAlignment");
                }
            }
        }

        #endregion  Public Propetries
    }
}
